import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author 龙小虬
 * Long、Integer、Short、Byte缓存区间是在-128~127，会直接存在常量池中，而不在这个区间内对象的值则会每次都new一个对象，那么即使两个对象的值相同，CAS方法都会返回false
 * @date 2021/4/23 13:49
 */
public class AtomicStampedReferenceTest {
    // 先声明初始值，修改后的值和临时的值是为了保证使用CAS方法不会因为对象不一样而返回false
    private static final Integer INIT_NUM = 100;
    private static final Integer UPDATE_NUM = 200;

    private static AtomicStampedReference atomicStampedReference = new AtomicStampedReference(INIT_NUM, 1);

    public static void main(String[] args) {
        new Thread(() -> {
            Integer value = (Integer) atomicStampedReference.getReference();
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName() + " : 当前值为：" + value + " 版本号为：" + stamp);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //第一个参数expectedReference：表示预期值
            //第二个参数newReference：表示要更新的值
            //第三个参数expectedStamp：表示预期的时间戳
            //第四个参数newStamp：表示要更新的时间戳。
            if (atomicStampedReference.compareAndSet(value, UPDATE_NUM, 1, stamp + 1)) {
                System.out.println(Thread.currentThread().getName() + " : 当前值为：" + atomicStampedReference.getReference() + " 版本号为：" + atomicStampedReference.getStamp());
            } else {
                System.out.println("版本号不同，更新失败！");
            }
        }).start();
    }
}
